/* 192.168.10.1 */

const express = require('express'); // 导入 Express 模块，用于创建 Web 服务器
const cors = require('cors'); // 导入 CORS 模块，用于解决跨域请求的问题
const fs = require('fs'); // 导入 fs 模块，用于操作文件系统（如读取文件）
const path = require('path'); // 导入 path 模块，用于处理和操作文件路径

const app = express(); // 创建 Express 应用实例

app.use(cors()); // 启用 CORS 中间件，允许跨域请求

// 配置静态文件服务，使得 /public 目录下的文件可以通过 URL 直接访问
app.use('/public', express.static(path.join(__dirname, 'public')));

// 定义存放 app 版本文件的目录路径
const appDir = path.join(__dirname, 'public/apps');

// 服务器的 IP 地址，作为下载地址的一部分使用
// let serverAddress = 'http://8.130.66.190';
// let serverAddress = 'http://8.130.66.190';

// http://192.168.10.244:8080/
let serverAddress = 'http://192.168.10.244';

/**
 * 根据客户端提供的版本号检查是否有新版本。
 * 如果有新版本，返回版本信息和下载链接，否则不做更新。
 */
app.get('/checkForUpdate/:version', async (req, res) => {

	// 从请求参数中获取客户端的当前版本号
	const appCurrentVersion = req.params.version;

	// 定义最新的 app 版本号，初始为空
	let appLatestVersion = '';

	try {
		// 读取 app 文件夹中的所有文件
		const files = fs.readdirSync(appDir);

		// 过滤出以 'app' 开头的文件（表示 app 更新包）
		const appFiles = files.filter(file => path.basename(file).startsWith('app'));

		// 对文件列表进行排序，根据文件名中的版本号进行升序排列
		const sortedFiles = appFiles.sort((a, b) => {
			const aParts = a.split('.').map(Number); // 将文件名按 "." 分割并转换为数字数组
			const bParts = b.split('.').map(Number);

			// 按每部分数字进行比较，决定排序顺序
			for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
				if (aParts[i] > bParts[i]) return 1;
				if (aParts[i] < bParts[i]) return -1;
			}

			return 0;
		});

		// 获取最新版本的文件名（排序后的最后一个文件）
		appLatestVersion = sortedFiles.pop();

		// 将文件名中的 'app' 前缀和 '.wgt' 后缀去掉，得到版本号
		appLatestVersion = appLatestVersion.replace(/^app/, '').replace(/\.wgt$/, '');

	} catch (error) {
		// 如果读取文件夹失败，抛出错误
		throw new Error('Error reading public directory:' + error);
	}

	// 检查客户端版本是否小于最新版本
	if (appLatestVersion > appCurrentVersion) {
		// 如果有新版本，返回版本信息和下载链接
		res.send({
			version: appLatestVersion, // 返回最新版本号
			url: `${serverAddress}/downloadApp/${appLatestVersion}`, // 返回下载链接
			update: true, // 标记为有更新
			mandatoryUpdate: true // 强制更新（不更新则无法继续使用）
		});
	} else {
		// 没有新版本，返回无需更新的信息
		res.send({
			version: '', // 无需更新，返回空版本号
			url: '', // 无需下载链接
			update: false, // 标记为无更新
			mandatoryUpdate: false // 非强制更新
		});
	}
});

/**
 * 提供 app 更新包的文件下载服务。
 * 根据请求的版本号，返回对应版本的 app 安装包。
 */
app.get('/downloadApp/:version', async (req, res) => {
	// 获取请求的版本号
	const version = req.params.version;
	const appName = `app${version}.wgt`; // 构建下载的文件名
	const appFilePath = `${appDir}/${appName}`; // 构建文件的完整路径

	// 检查文件是否存在
	fs.stat(appFilePath, (err, stats) => {
		if (err) {
			// 如果文件不存在，抛出错误
			throw new Error(`未找到 app${version}版本下载地址`);
		}

		// 设置响应头，告诉浏览器将文件作为下载进行处理
		res.setHeader('Content-Disposition', `attachment; filename=${appName}`);
		res.setHeader('Content-Type', 'application/octet-stream'); // 设置文件类型为二进制流

		// 创建文件读取流
		const fileStream = fs.createReadStream(appFilePath);

		// 当文件流结束时，关闭响应
		fileStream.on('end', () => {
			console.log('File download completed.');
		});

		// 处理文件流中的错误
		fileStream.on('error', (error) => {
			throw new Error('Error downloading the file.:' + error);
		});

		// 将文件流传输到客户端
		fileStream.pipe(res);
	});
});

const port = 3001; // 定义服务器监听的端口号

// 启动服务器并监听指定的端口
const server = app.listen(port, () => {
	// 获取服务器的地址信息
	const addressInfo = server.address();
	

	// const host = addressInfo.address === '::' ? '8.130.66.190' : addressInfo.address; // 处理 IPv6 地址
	const host = addressInfo.address === '::' ? '192.168.10.244' : addressInfo.address; // 处理 IPv6 地址
	const port = addressInfo.port; // 获取监听的端口号


	// 更新 serverAddress，确保正确的地址用于下载链接
	serverAddress = `http://${host}:${port}`;

	// 打印服务器启动信息
	console.log(`Server is running at http://${host}:${port}`);
});